package controllerInterfaces;

import java.io.File;
import java.util.List;

import model.Project;
import model.Test;
import modelInterfaces.IProject;
import modelInterfaces.ITest;
import pluginInterfaces.IMetric;
import pluginInterfaces.IRecommender;
import viewInterfaces.IViewMain;
import controller.ControllerMain;
import enums.StatusProject;
import enums.Use;

/**
 *
 * Interface of {@link ControllerMain} controller class according to Abstract Factory design pattern.
 */
public interface IControllerMain extends IFrameController {

	/**
	 * Get the list of current {@link Project} {@link Recommender}.</br>
	 * Each of the obtained {@link Recommender} is manipulable through its {@link IRecommender} interface.
	 * @return	list of current {@link Project} {@link Recommender}.
	 * @see 	IRecommender
	 * @see		Project
	 * @see		Recommender
	 */	
	public List<IRecommender> getRecommenderList();
	

	/**
	 * Saves the list of current {@link Project} {@link Recommender}.</br>
	 * Each of the saved {@link Recommender} is manipulable through its {@link IRecommender} interface.
	 * @param	reocommenderList	list of {@link IRecommender}
	 * @see 	IRecommender
	 * @see		Project
	 * @see		Recommender
	 */	
	public void setRecommenderList(List<IRecommender> recommenderList);
	

	/**
	 * Instance the controller manages the execution of a {@link Recommender}.
	 * @param	recommender	recommendation algorithm to execute
	 * @see		Recommender
	 */
	public void startRunSetup(IRecommender recommender);
	
	
	/**
	 * Finish the controllar manages the execution of a {@link Recommender}.
	 * @see		Recommender 
	 */
	public void stopRun();
	
	
	/**
	 * Instance the controller manages the database connection.
	 */
	public void startDBConnectionSetup();
	
	
	/**
	 * Finish the controller manages the database connection.
	 */
	public void stopDBConnectionSetup();
	
	
	/**
	 * Instance the controller performs I/O actions ({@link Use}) on a {@link Project}
	 * @param	use		the action to will perform on a {@link Project}
	 * @see 	Use
	 * @see 	Project
	 */		
	public void startProjectManagement(Use use);
	
	
	/**
	 * Finish the controller performs I/O actions ({@link Use}) on a {@link Project}
	 * @see 	Use
	 * @see 	Project
	 */	
	public void stopProjectManagement();
	
	
	/**
     * Terminates normally the application
     */
	public void normalExit();
	
	
	/**
     * Terminates abnormally the application
     */
    public void abnormalExit();
	
	
	/**
	 * Get the {@link ViewMain}.
	 * {@link ViewMain} is manipulable through {@link IViewMain} interface.
	 * @return 	IViewMain	interface of {@link ViewMain]
	 * @see ViewMain
	 * @see IViewMain	
	 */
	public IViewMain getViewMain();
	
	
	/**
	 * Get the current {@link Project}.</br>
	 * The {@link Project} is manipulable through {@link IProject} interface
	 * @return IProject	interface of {@link Project}
	 * @see Project
	 * @see IProject
	 */
	public IProject getProject();
	
	
	/**
	 * Save the current {@link Project}
	 * The {@link Project} is manipulable through {@link IProject} interface
	 * @param	project	The project to save
	 * @see 	Project
	 * @see 	IProject
	 */
	public void setProject(IProject project);
	
	
	/**
	 * Set the {@link Project} name in window title
	 * @param 	name	{@link Project} name
	 * @see		ViewMain
	 */
	public void setProjectNameInView(String name);
	
	
	
	public boolean removeAlgorithmIntoTest(int index);
	
	
	/**
	 * Get the list of current {@link Project} {@link Test}.</br>
	 * Each of the obtained {@link Test} is manipulable through its {@link ITest} interface.
	 * @return	list of current project tests
	 * @see 	ITest
	 * @see		Test
	 */
	public List<ITest> getTestList();
	
	
	/**
	 * Saves the list of current {@link Project} {@link Test}.</br>
	 * Each of the saved {@link Test} is manipulable through its {@link ITest} interface.
	 * @param	testList	list of {@link ITest}
	 * @return	list of current {@link Project} {@link Test}.
	 * @see 	ITest
	 * @see		Project
	 * @see		Test
	 */
	public void setTestList(List<ITest> testList);
	
	
	/**
	 * Get the list of current {@link Project} {@link Metric}.</br>
	 * Each of the obtained {@link Metric} is manipulable through its {@link IMetric} interface.
	 * @return	list of current {@link Project} {@link Metric}.
	 * @see 	IMetric
	 * @see		Project
	 * @see		Metric
	 */		
	public List<IMetric> getMetricList();
	
	
	public void removeMetricIntoTest(int index);
	
	
	/**
	 * Block each of panels of {@link ViewMain}.
	 * @see ViewMain
	 */	
	public void BlockPanels();
	
	
	/**
	 * Unblock each of panels of {@link ViewMain}.
	 * @see ViewMain
	 */
	public void UnBlockPanels();
	

	/**
	 * Set the status of {@link Project} as created and realize operations</br>
	 * for refresh view and controller status.
	 */ 
	public void StatusProjectCreated();	
	
	/**
	 * Set the status of {@link Project} as modified and realize operations</br>
	 * for refresh view and controller status.
	 */
	public void StatusProjectModified();
	
	
	
	/**
	 * Set the status of {@link Project} as saved and realize operations</br>
	 * for refresh view and controller status.
	 */
	public void StatusProjectSaved();	

	
	
	/**
	 * Indicate if {@link Project} status is modified.
	 * @return true when project status is modified, otherwise false.
	 * @see Project 
	 */
	public boolean isModifiedProject();

	
	
	/**
	 * Set selected file associated with {@link Project}. 
	 * @param oi object input stream.
	 * @see Project
	 */
	public void SetSelectedFile(File sFile);
	
	
	/**
	 * Get selected file associated with {@link Project}. 
	 * @return file associated with project.
	 * @see Project
	 */
	public File GetSelectedFile();


	/**
	 * Set status of database connection according to parameter value.
	 * @param value	if true then database connection status is connected, otherwise, disconnected .
	 */
	public void setDBConnectedStatus(boolean value);


	/**
	 * Get status of DB connection.
	 * @return if true then database connection exists, otherwise, doesn't exist .
	 */
	public boolean getDBConnectedStatus();	
	

	/**
	 * Set status of project according to parameter value.
	 * @param value	if true then project status is enabled, otherwise, disabled .
	 */
	public void setProjectStatus(boolean value);

	
	/**
	 * Set status of project in controller and view levels according to parameter value and status.
	 * @param value	if true then project status is enabled, otherwise, disabled .
	 * @param status status of project
	 */
	public void setProjectStatus(boolean value, StatusProject status);	
	
	
	/**
	 * Get status of project.
	 * @return if true then project status is enabled, otherwise, disabled .
	 */
	public boolean getProjectStatus();
	

	/**
	 * Get ControllerProjectManagement Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerProjectManagement
	 */
	public IControllerProjectManagement getControllerProjectManagement();


	/**
	 * Get ControllerRecommendersPanel Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerRecommendersPanel
	 */	
	public IControllerRecommendersPanel getControllerRecommendersPanel();


	/**
	 * Get ControllerMetricsPanel Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerMetricsPanel
	 */		
	public IControllerMetricsPanel getControllerMetricsPanel();

	
	/**
	 * Get ControllerTestsPanel Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerProjectManagement
	 */	
	public IControllerTestsPanel getControllerTestPanel();


	/**
	 * Get ControllerBenchmarkPanel Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerBenchmarkPanel
	 */	
	public IControllerBenchmarkPanel getControllerBecnhmarkPanel();


	/**
	 * Get ControllerDBConnectionSetup Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerDBConnectionSetup
	 */		
	public IControllerDBConnectionSetup getControllerDBConnectionSetup();


	/**
	 * Get ControllerRunSetup Interface.</br>
	 * This method is only used for realize unit testing.
	 * @return IControllerRunSetup
	 */		
	public IControllerRunSetup getControllerRun();
	
	
	
	/**
	 * Indicate if application is running on debug mode.
	 * @return value of debug mode.
	 */
	public boolean isDebug();
	
	/**
	 * Indicates RBox Version
	 * @return RBox version
	 */
	public String getRboxVersion();
	
}
